﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Web.Script.Serialization;
using System.Text.RegularExpressions;
using MvcApplication5.Common;

namespace MyFrameWork.Common
{
    /// <summary>
    /// JSON操作实用类
    /// </summary>
    public class JsonUtility
    {
        /// <summary>
        /// 将JSON文字列转化成C#对象
        /// </summary>
        /// <typeparam name="T">JSON文字列</typeparam>
        /// <param name="jsonString"></param>
        /// <returns>C#对象</returns>
        public static T Parse<T>(string jsonString)
        {
            //实例化一个能够序列化数据的类
            JavaScriptSerializer json = new JavaScriptSerializer();
            return json.Deserialize<T>(jsonString);
        }

        /// <summary>   
        /// 将JSON文字列转化成DataSet
        /// </summary>   
        /// <param name="strJson">JSON文字列</param>   
        /// <returns>DataSet</returns>   
        public static DataSet ParseDataSet(string strJson)
        {
            //创建序列化器
            JavaScriptSerializer s = new JavaScriptSerializer();

            //反序列化成键值集合
            try
            {
                //反序列化JSon
                Dictionary<string, object> JsonData = (Dictionary<string, object>)s.DeserializeObject(strJson);
                if (JsonData.Count < 1) { return new DataSet(); }

                //生成DataSet
                DataSet ds = new DataSet();
                foreach (KeyValuePair<string, object> tableItem in JsonData)
                {
                    if (tableItem.Value.GetType() != typeof(Object[]) || ((Object[])tableItem.Value).Length < 1) { continue; }

                    //生成DataTable
                    DataTable dt = new DataTable(tableItem.Key);
                    foreach (Object rowItem in (Object[])tableItem.Value)
                    {
                        if (rowItem as Dictionary<string, object> == null) { continue; }

                        //生成DataColumn
                        if (dt.Columns.Count < 1)
                        {
                            foreach (KeyValuePair<string, object> colItem in (Dictionary<string, object>)rowItem)
                            {
                                dt.Columns.Add(colItem.Key);
                            }
                        }

                        //生成DataRow
                        DataRow dr = dt.NewRow();
                        foreach (KeyValuePair<string, object> colItem in (Dictionary<string, object>)rowItem)
                        {
                            //生成ColumnData
                            if (dt.Columns.Contains(colItem.Key))
                            {
                                dr[colItem.Key] = colItem.Value;
                            }
                        }

                        dt.Rows.Add(dr);
                    }

                    ds.Tables.Add(dt);
                }

                return ds;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>   
        /// 将JSON文字列转化成DataTable   
        /// </summary>   
        /// <param name="strJson">JSON文字列</param>   
        /// <returns>DataTable</returns>   
        public static DataTable ParseDataTable(string strJson)
        {
            DataSet dsRet = ParseDataSet(strJson);
            if (dsRet.Tables.Count > 0)
            {
                return dsRet.Tables[0];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 将C#对象转化成JSON文字列
        /// </summary>
        /// <param name="jsonObject">C#对象</param>
        /// <returns>JSON文字列</returns>
        public static string ToJSON(object jsonObject)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            jss.MaxJsonLength = Int32.MaxValue;
            String json = jss.Serialize(jsonObject);

            //1970/01/01以前日期特殊化处理
            json = Regex.Replace(json, @"\\/Date\((-\d+)\)\\/", match =>
            {
                DateTime dt = new DateTime(1970, 1, 1);
                dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));
                dt = dt.ToLocalTime();
                return dt.ToString(CmnConsts.DATE_TIME);
            });

            return json;
        }

        /// <summary>
        /// 将DataSet转化成JSON文字列
        /// </summary>
        /// <param name="dsSource">DataSet</param>
        /// <returns>JSON文字列</returns>
        public static string ToJSON(DataSet dsSource)
        {
            String colData = String.Empty;
            StringBuilder sb = new StringBuilder();
            Int32 tableIndex = 0, rowIndex = 0, colIndex = 0;

            if (dsSource.Tables.Count < 1) return "";

            sb.Append("{");

            //DataTable
            tableIndex = 0;
            foreach (DataTable dt in dsSource.Tables)
            {
                //数据不存在
                if (dt.Rows.Count < 1)
                {
                    sb.Append(dt.TableName + ":{}");
                    if (tableIndex < dsSource.Tables.Count - 1)
                    {
                        sb.Append(",");
                    }

                    tableIndex++;
                    continue;
                }

                sb.Append(dt.TableName + ":[");

                //DataRow
                rowIndex = 0;
                foreach (DataRow dr in dt.Rows)
                {
                    sb.Append("{");

                    //DataColumn
                    colIndex = 0;
                    foreach (DataColumn dc in dt.Columns)
                    {
                        if (dr[dc] == null)
                        {
                            colData = "";
                        }
                        else
                        {
                            colData = dr[dc].ToString().Replace("\\", "\\\\").Replace("\r", "\\r").Replace("\n", "\\n").Replace("\"", "\\\"").Trim();
                            colData = colData.Replace("(", "\\u0028").Replace(")", "\\u0029").Replace("[", "\\u005B").Replace("]", "\\u005D").Replace("{", "\\u007B").Replace("]", "\\u007D");
                            if (colData == null) colData = string.Empty;
                        }

                        if (dc.DataType == typeof(bool) && colData.ToString().Trim().ToUpper() == "TRUE")
                        {
                            sb.Append("\"" + dc.ColumnName + "\":true");
                        }
                        else if (dc.DataType == typeof(bool) && colData.ToString().Trim().ToUpper() == "FALSE")
                        {
                            sb.Append("\"" + dc.ColumnName + "\":false");
                        }
                        else if (dc.DataType == typeof(DateTime))
                        {
                            if (string.IsNullOrEmpty(colData))
                                sb.Append("\"" + dc.ColumnName + "\":\"\"");
                            else
                                sb.Append("\"" + dc.ColumnName + "\":\"" + DateTime.Parse(colData).ToString(CmnConsts.DATE_TIME) + "\"");
                        }
                        else
                        {
                            sb.Append("\"" + dc.ColumnName + "\":\"" + colData + "\"");
                        }

                        if (colIndex < dt.Columns.Count - 1)
                        {
                            sb.Append(",");
                        }

                        colIndex++;
                    }

                    sb.Append("}");

                    if (rowIndex < dt.Rows.Count - 1)
                    {
                        sb.Append(",");
                    }

                    rowIndex++;
                }

                sb.Append("]");

                if (tableIndex < dsSource.Tables.Count - 1)
                {
                    sb.Append(",");
                }

                tableIndex++;
            }

            sb.Append("}");
            return sb.ToString();
        }

        /// <summary>
        /// 将DataTable转化成JSON文字列
        /// </summary>
        /// <param name="dsSource">DataTable</param>
        /// <returns>JSON文字列</returns>
        public static string ToJSON(DataTable dtSource)
        {
            string strJson = string.Empty;

            DataSet dsSource = new DataSet();
            dsSource.Tables.Add(dtSource.Copy());
            strJson = ToJSON(dsSource);

            return strJson;
        }

        /// <summary>
        /// 検索結果JSON文字列を作成する
        /// </summary>
        /// <param name="pagerJson">ページJSON文字列</param>
        /// <param name="dataJson">データJSON文字列</param>
        /// <returns>検索結果JSON文字列</returns>
        public static string CreateSearchResultJson(String pagerJson, String dataJson)
        {
            return "{Pager:" + pagerJson + ",Data:" + dataJson + "}";
        }
    }
}